package com.promote.hotspot.server.counter;

import com.promote.hotspot.server.config.JetcdConfig;
import lombok.extern.java.Log;
import org.promote.hotspot.common.config.ConfigConstant;
import org.promote.hotspot.common.etcd.JetcdClient;
import org.promote.hotspot.common.model.KeyCountModel;
import org.promote.hotspot.common.tool.Constant;
import org.promote.hotspot.common.tool.FastJsonUtils;
import org.promote.hotspot.common.tool.IpUtils;
import org.promote.hotspot.common.tool.SystemClock;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 计数管理类
 *
 * @author enping.jep
 * @date 2024/02/29 17:13
 **/
@Component
@Log
public class CounterManager {

    @Resource
    private JetcdClient jetcdClient;
    public static LinkedBlockingQueue<KeyCountItem> COUNTER_QUEUE = new LinkedBlockingQueue<>();

    @PostConstruct
    public void beginConsume() {
        ExecutorService threadPoolExecutor = Executors.newSingleThreadExecutor();
        threadPoolExecutor.submit(() -> {
            while (true) {
                Map<String, String> map = new HashMap<>(500);
                KeyCountItem item = COUNTER_QUEUE.take();
                //每个List是一个client的10秒内的数据，一个rule如果每秒都有数据，那list里就有10条
                List<KeyCountModel> keyCountModels = item.getList();
                String appName = item.getAppName();
                for (KeyCountModel keyCountModel : keyCountModels) {
                    //如 rule + Constant.COUNT_DELIMITER + nowTime;
                    //rule + 分隔符 + 2020-10-23 21:11:22
                    //pin__#**#2020-10-23 21:11:22
                    String ruleKey = keyCountModel.getRuleKey();
                    int hotHitCount = keyCountModel.getHotHitCount();
                    int totalHitCount = keyCountModel.getTotalHitCount();
                    //key：ConfigConstant.keyHitCountPath + appName + "/" + IpUtils.getIp() + "-" + System.currentTimeMillis()
                    String mapKey = appName + Constant.COUNT_DELIMITER + ruleKey;
                    if (map.get(mapKey) == null) {
                        map.put(mapKey, hotHitCount + "-" + totalHitCount);
                    } else {
                        String[] counts = map.get(mapKey).split("-");
                        int hotCount = Integer.parseInt(counts[0]) + hotHitCount;
                        int totalCount = Integer.parseInt(counts[1]) + totalHitCount;
                        map.put(mapKey, hotCount + "-" + totalCount);
                    }
                }
                //300是什么意思呢？300就代表了300秒的数据了，已经不少了
                //todo 暂时改成1s 方便调试
                if (map.size() >= 300) {
                    jetcdClient.putWithLease(ConfigConstant.KEY_HIT_COUNT_PATH + appName + "/" + IpUtils.getIp() + "-" + SystemClock.now(), FastJsonUtils.convertObjectToJSON(map), 30);
                    log.info("key Hit count : " + map);
                    map.clear();
                }

            }
        });
    }
}
